export class UploadController {
  private requestStrategy: RequestStrategy; // 请求策略，没有传递则使用默认策略
  private splitStrategy: ChunkSplitor; // 分片策略，没有传递则默认多线程分片
  private taskQueue: TaskQueue; // 任务队列
  // 其他属性略

  // 初始化
  async init() {
    // 获取文件token
    this.token = await this.requestStrategy.createFile(this.file);
    // 分片事件监听
    this.splitStrategy.on("chunks", this.handleChunks.bind(this));
    this.splitStrategy.on("wholeHash", this.handleWholeHash.bind(this));
  }

  // 分片事件处理
  private handleChunks(chunks: Chunk[]) {
    // 分片上传任务加入队列
    chunks.forEach((chunk) => {
      this.taskQueue.addAndStart(new Task(this.uploadChunk.bind(this), chunk));
    });
  }

  async uploadChunk(chunk: Chunk) {
    // hash校验
    const resp = await this.requestStrategy.patchHash(this.token, chunk.hash, "chunk");
    if (resp.hasFile) {
      // 文件已存在
      return;
    }
    // 分片上传
    await this.requestStrategy.uploadChunk(chunk, this.uploadEmitter);
  }

  // 整体hash事件处理
  private async handleWholeHash(hash: string) {
    // hash校验
    const resp = await this.requestStrategy.patchHash(this.token, hash, "file");
    if (resp.hasFile) {
      // 文件已存在
      this.emit("end", resp.url);
      return;
    }
    // 根据resp.rest重新编排后续任务
    // ...
  }
}
